﻿using Jaina;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.RateLimiting;
using System.Threading.Tasks;
using TouchSocket.Sockets;
using YS.Domain.IoT.Const;
using YS.Domain.IoT.Extension;
using YS.Domain.IoT.Model;
using YS.K12.Application.IoT.RedisHub;
using YS.K12.Application.IoT.Service;

namespace YS.K12.Core.IoT.Plugin
{
    /// <summary>
    ///连接处理插件
    /// </summary>
    public class TcpConnectPlugin : PluginBase, ITcpConnectingPlugin, ITcpConnectedPlugin, ITcpClosingPlugin, ITcpClosedPlugin, IIdChangedPlugin
    {
        public readonly ILogger<TcpReceivedPlugin> _logger;
        private readonly IHttp _http;
        private readonly RedisHubLifetimeManager _redisHub;
        public TcpConnectPlugin(
             ILogger<TcpReceivedPlugin> logger,
             IHttp http,
             RedisHubLifetimeManager redisHub)
        {
            _logger = logger;
            _http = http;
            _redisHub = redisHub;
        }
        /// <summary>
        /// 当SocketClient的ID发生改变时触发。
        /// </summary>
        /// <param name="client"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task OnIdChanged(IClient client, IdChangedEventArgs e)
        {
            _logger.LogInformation($" 设备已成功登录");
            await e.InvokeNext();
        }

        public async Task OnTcpClosed(ITcpSession client, ClosedEventArgs e)
        {
            var mid = client.GetClientId();
            _logger.LogInformation($" 客户端 id:{mid},addr:{client.IP}:{client.Port},online:{client.Online} 已成功主动退出登录,最后接收时间{client.LastReceivedTime}");
            // 从登录状态字典中移除该客户端的登录信息
            client.TryGetAuth(out bool isLoggedIn);
            if (isLoggedIn)//先判断是否登录成功了 避免多余的操作
            {
                //删除登录授权    
                client.RemoveAuth();
                //修改数据库
                await _http.SetVendLineStatus(new Application.IoT.Service.Dto.VendLineStatusInput()
                {
                    LineStatus = false,
                    VendCode = mid,
                });
                ///删除Redis连接通道
                var cacheKey = CacheConst.VendChannelKey.ToFormat(mid);
                await RedisHelper.DelAsync(cacheKey);
                //删除订阅通道
                _redisHub.UnsubscribeFromConnection(mid);
            }
            await e.InvokeNext();
        }
        /// <summary>
        /// 心跳断开连接
        /// </summary>
        /// <param name="client"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        public Task OnTcpClosing(ITcpSession client, ClosingEventArgs e)
        {
            var mid = client.GetClientId();
            _logger.LogInformation($" 客户端 id:{mid},addr:{client.IP}:{client.Port},online:{client.Online},最后接收时间:{client.LastReceivedTime},准备断开，信息：{e.Message}");

            return e.InvokeNext();
        }

        /// <summary>
        /// 同意连接，且成功启动接收后触发
        /// </summary>
        /// <param name="client"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task OnTcpConnected(ITcpSession client, ConnectedEventArgs e)
        {
            // ConsoleLogger.Default.Info($"客户端{client.GetClientId()}:连接成功");
            return e.InvokeNext();
        }
        /// <summary>
        ///	此时Socket实际上已经完成连接，但是并没有启动接收，然后触发。
        /// </summary>
        /// <param name="client"></param>
        /// <param name="e"></param> 
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task OnTcpConnecting(ITcpSession client, ConnectingEventArgs e)
        {
            e.IsPermitOperation = true;
            await _redisHub.EnsureRedisServerConnection();
            _logger.LogInformation($"客户端{client.GetIPPort()}:连接");
            await e.InvokeNext();
        }
    }
}
